/**
 * Project:   warnme-server
 * File:      ProfileRestWS.java
 * License: 
 *            This file is licensed under GNU General Public License version 3
 *            http://www.gnu.org/licenses/gpl-3.0.txt
 *
 * Copyright: Bartlomiej Gebski [ b.k.gebski@gmail.com ]
 * Date:      19-03-2014
 */

package dtu.ds.warnme.ws.rest.json.impl;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.gson.JsonParseException;

import dtu.ds.warnme.exceptions.impl.BadRequestException;
import dtu.ds.warnme.exceptions.impl.ServiceException;
import dtu.ds.warnme.model.impl.EventEntity;
import dtu.ds.warnme.model.impl.EventType;
import dtu.ds.warnme.services.EventsService;
import dtu.ds.warnme.ws.rest.json.AbstractRestWS;
import dtu.ds.warnme.ws.rest.json.gson.GsonHolder;
import dtu.ds.warnme.ws.rest.json.utils.RestUtils;

/**
 * @author Bartlomiej Gebski
 */
@Controller
@RequestMapping(value = "/events")
public class EventRestWS extends AbstractRestWS {

	private static final String ACTION_DOWNVOTE = "downvote";

	private static final String ACTION_UPVOTE = "upvote";

	@Autowired
	private EventsService eventsService;

	@PreAuthorize("hasRole('USER')")
	@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
	void actionOnEvent(HttpServletRequest request, HttpServletResponse response, @PathVariable String id, @RequestParam(value = "action",
	        required = false) String action) throws BadRequestException, ServiceException {
		if (ACTION_UPVOTE.equals(action)) {
			eventsService.upvoteEvent(id);
		} else if (ACTION_DOWNVOTE.equals(action)) {
			eventsService.downvoteEvent(id);
		} else {
			throw new BadRequestException("Invalid action!", "exceptions.badRequestExceptions.invalidAction");
		}
	}

	@PreAuthorize("hasRole('USER')")
	@RequestMapping(method = RequestMethod.GET, produces = RestUtils.CONTENT_APPLICATION_JSON_UTF8)
	@ResponseBody
	String getAllEvents(HttpServletRequest request, HttpServletResponse response,
	        @RequestParam(value = "latitude", required = false) Float latitude,
	        @RequestParam(value = "longitude", required = false) Float longitude,
	        @RequestParam(value = "bearing", required = false) Float bearing,
	        @RequestParam(value = "eventTypes", required = false) EventType[] types,
	        @RequestParam(value = "radius", required = false) Float radius) throws BadRequestException, ServiceException {
		if (latitude == null || longitude == null || bearing == null || radius == null) {
			throw new BadRequestException("You must provide all the info - longitude, latitude, bearing and radius",
			        "exceptions.badRequestExceptions.eventParameterMissing");
		}
		String json = GsonHolder.getGson(GsonHolder.RESTRICTED)
		        .toJson(eventsService.getEvents(latitude, longitude, bearing, radius, types));
		RestUtils.decorateResponseHeaderWithMD5(response, json);
		return json;
	}

	@PreAuthorize("hasRole('USER')")
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	@ResponseBody
	String getEvent(HttpServletRequest request, HttpServletResponse response, @PathVariable String id) throws BadRequestException,
	        ServiceException {
		String json = GsonHolder.getGson(GsonHolder.RESTRICTED).toJson(eventsService.getEvent(id));
		RestUtils.decorateResponseHeaderWithMD5(response, json);
		return json;
	}

	@PreAuthorize("hasRole('USER')")
	@RequestMapping(method = RequestMethod.POST)
	void registerEvent(HttpServletRequest request, HttpServletResponse response) throws ServiceException, BadRequestException {
		String requestBody = RestUtils.getRequestBody(request);
		if (StringUtils.isBlank(requestBody)) {
			throw new BadRequestException("You can't register \"nothing\".", "exceptions.badRequestExceptions.cantRegisterNothing");
		}
		try {
			EventEntity event = GsonHolder.getGson().fromJson(requestBody, EventEntity.class);
			eventsService.registerEvent(event);
		} catch (JsonParseException ex) {
			throw new BadRequestException("Error in submitted JSON!", "exceptions.badRequestExceptions.badJson", ex);
		}
	}

}
